package gao.xiaolei.my_network_listener_plugin;

import android.content.Context;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.NonNull;
import java.util.HashMap;
import java.util.Map;
import gao.xiaolei.my_network_listener_plugin.callback.NetworkChangeCallback;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry.Registrar;

/** MyNetworkListenerPlugin */
public class MyNetworkListenerPlugin implements FlutterPlugin{
  /// The MethodChannel that will the communication between Flutter and native Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine and unregister it
  /// when the Flutter Engine is detached from the Activity
  private final String EVENT_CHANNEL = "my.flutter.event/network";
  private EventChannel.EventSink mySink;//flutter中订阅了要接收我发出的消息的观察者们
  private Handler mHandler = new Handler(Looper.getMainLooper());//handle的作用是为了在主线程中向flutter返回消息,Flutter1.7.8版本添加了线程安全，需要原生在主线程中返回给Flutter
  private ConnectivityManager mNetworkManager;//本地网络管理
  private NetworkListener mNetworkListener;//网络监听对象
  private Context context;

  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    context=flutterPluginBinding.getApplicationContext();
    mNetworkManager=(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);//调用系统服务获取本地网络管理对象
    mNetworkListener=new NetworkListener(networkChangeCallback,mNetworkManager);//构建网络监听器
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
    context.registerReceiver(mNetworkListener,intentFilter);//将我们自己的监听对象注册到上下文
    new EventChannel(flutterPluginBinding.getBinaryMessenger(), EVENT_CHANNEL).setStreamHandler(new EventChannel.StreamHandler() {//创建对flutter的消息发送channel
      @Override
      public void onListen(Object o, EventChannel.EventSink eventSink) {//当flutter中有人要订阅我们发送的消息时就会调用这个函数
        System.out.println("添加了一个观察者");
        mySink=eventSink;//设置观察者
        sendNetworkState(mNetworkListener.currentNetworkIsAvailable());//先直接向flutter发送网络状态,让其有个初始值
      }
      @Override
      public void onCancel(Object o) {//当flutter中有人要取消订阅我们发送的消息时就会调用这个函数
        System.out.println("删除了一个观察者");
        mySink=null;//将观察者移除
      }
    });
  }

  // This static function is optional and equivalent to onAttachedToEngine. It supports the old
  // pre-Flutter-1.12 Android projects. You are encouraged to continue supporting
  // plugin registration via this function while apps migrate to use the new Android APIs
  // post-flutter-1.12 via https://flutter.dev/go/android-project-migration.
  //
  // It is encouraged to share logic between onAttachedToEngine and registerWith to keep
  // them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called
  // depending on the user's project. onAttachedToEngine or registerWith must both be defined
  // in the same class.
  public static void registerWith(Registrar registrar) {

  }

  private NetworkChangeCallback networkChangeCallback= isAvailable -> {
    sendNetworkState(isAvailable);
  };

  private void sendNetworkState(boolean isAvailable){//向flutter发送网络状态消息
    if(isAvailable){//如果网络可用
      Map<String,Object> successData=new HashMap<>(1);
      successData.put("code","80001");
      sendSuccessMsgToEventChannel(successData);//向flutter发送网络断开的消息
    }else//如果网络连接不可用
      sendFailMsgToEventChannel("90001", "网络连接不可用", null);//向flutter发送消息
  }

  //向观察者们轮询发送成功消息
  private void sendSuccessMsgToEventChannel(Object msg){
    if(mySink!=null)
      runOnMainThread(()->{
        mySink.success(msg);
      });
  }

  //向观察者们轮询发送失败消息
  private void sendFailMsgToEventChannel(String errCode, String errMsg, Object errDetail){
    if(mySink!=null)
      runOnMainThread(()->{
        mySink.error(errCode,errMsg,errDetail);
      });
  }

  /**
   * 判断当前线程是否是主线程
   *
   */
  private boolean isMainThread() {
    return Looper.myLooper() == Looper.getMainLooper();
  }

  /**
   * 将目标代码快运行在主线程中
   *
   */
  private void runOnMainThread(Runnable runnable) {
    if (isMainThread()) {
      runnable.run();
    } else {
      if (mHandler != null) {
        mHandler.post(runnable);
      }
    }
  }
  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
  }
}
